//
//  GRFMResourceLoaderDelegate.m
//  GRFMRemotePlayer_Example
//
//  Created by GR on 2018/1/17.
//  Copyright © 2018年 guorui. All rights reserved.
//

#import "GRFMResourceLoaderDelegate.h"
#import "GRRemotePlayerFileManager.h"
#import "NSURL+Steam.h"
#import "GRAudioDownloader.h"

@interface GRFMResourceLoaderDelegate()<GRAudioDownloaderDelegate>
@property (strong, nonatomic) GRAudioDownloader *downloader;
@property (strong, nonatomic) NSMutableArray *loadingRequestList;
@end

@implementation GRFMResourceLoaderDelegate

- (GRAudioDownloader *)downloader {
    
    if (!_downloader) {
        _downloader = [[GRAudioDownloader alloc] init];
        _downloader.delegate = self;
    }
    return _downloader;
}

- (NSMutableArray *)loadingRequestList
{
    if (!_loadingRequestList) {
        _loadingRequestList = [NSMutableArray arrayWithCapacity:0];
    }
    return _loadingRequestList;
}

- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest
{
    NSLog(@"%p", loadingRequest);
   
//    [self loadLocalDataWithResourceRequest:loadingRequest];
    
    NSURL *url = [loadingRequest.request.URL httpURL];

    // 1. 判断cache 文件夹中是否有这个 url 的文件。
    BOOL cacheExists = [GRRemotePlayerFileManager cacheExistsWithURL:url];
    if (cacheExists) {
        // 加载本地完整的缓存数据
        [self loadLocalDataWithResourceRequest:loadingRequest];
        return YES;
    }

    [self.loadingRequestList addObject:loadingRequest];
    NSLog(@"loadingRequest.count = %zd", self.loadingRequestList.count);
    
//    @synchronized(self) {
    
        // 2. 判断是否有正在进行的请求
        BOOL requestRuning = self.downloader.loadedSize > 0;
        if (requestRuning == NO) {
            // 进行网路请求
            [self.downloader downloadWithURL:url offset:0];
            return YES;
        }

        // 3. 判断资源请求loadingRequest的开始位置，是否在当前请求完成tmp数据的范围内。
        // 3.1 不在范围内，重新请求，删除 tmp 缓存。
        long long requestOffset = loadingRequest.dataRequest.requestedOffset;
        long long currentOffset = loadingRequest.dataRequest.currentOffset;
        if (requestOffset != currentOffset) {
            requestOffset = currentOffset;
        }

        BOOL inTmpRange = requestOffset >= self.downloader.offset && requestOffset <= self.downloader.offset + self.downloader.loadedSize + 666;
        if (inTmpRange == NO) {
            // 重新进行请求，删除缓存
            [self.downloader downloadWithURL:url offset:requestOffset];
            return YES;
        }

        // 3.2 在范围内，将 tmp 数据取出播放。
        [self loadTmpDataWithResourceRequest];
//    }
    
    return YES;
}

- (void)resourceLoader:(AVAssetResourceLoader *)resourceLoader didCancelLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest
{
    NSLog(@"didCancelLoadingRequest - %p", loadingRequest);
    [self.loadingRequestList removeObject:loadingRequest];
}

#pragma mark - GRAudioDownloaderDelegate
- (void)downloading
{
    [self loadTmpDataWithResourceRequest];
}


#pragma mark - Private
- (void)loadTmpDataWithResourceRequest
{
    NSMutableArray *loadedRequestList = [NSMutableArray arrayWithCapacity:0];
    for (AVAssetResourceLoadingRequest *loadingRequest in self.loadingRequestList) {
        
        NSURL *url = [loadingRequest.request.URL httpURL];
        
        // 1. 信息头
        loadingRequest.contentInformationRequest.contentType = self.downloader.mineType;
        loadingRequest.contentInformationRequest.contentLength = self.downloader.totalSize;
        loadingRequest.contentInformationRequest.byteRangeAccessSupported = YES;
        
        // 2. 塞音频数据
        
        long long requestOffset = loadingRequest.dataRequest.requestedOffset;
        long long currentOffset = loadingRequest.dataRequest.currentOffset;
        NSInteger requestLength = loadingRequest.dataRequest.requestedLength;
        if (requestOffset != currentOffset) {
            requestOffset = currentOffset;
        }
        
        // 2.1 判断loadingRequest的请求返回是否在当前下载器缓存的文件的区域内.
//        if ((requestOffset >= self.downloader.offset && requestOffset <= self.downloader.offset + self.downloader.loadedSize) == NO) {
//            continue;
//        }

    
        // 2.2 在区域内则取出缓存数据。
        NSData *tmpData = [NSData dataWithContentsOfFile:[GRRemotePlayerFileManager tmpPathWithURL:url] options:NSDataReadingMappedIfSafe error:nil];
        if (tmpData == nil) {
            tmpData = [NSData dataWithContentsOfFile:[GRRemotePlayerFileManager cachePathWithURL:url] options:NSDataReadingMappedIfSafe error:nil];
        }
        
        NSUInteger dataLength = tmpData.length;
        long long responseOffset = requestOffset - self.downloader.offset;
        NSInteger responseLength = MIN(tmpData.length - responseOffset, requestLength);
        
        if ((responseOffset >= 0 && responseOffset < dataLength && (responseLength + responseOffset) <= dataLength) == NO) {
            continue;
        }
        
        [loadingRequest.dataRequest respondWithData:[tmpData subdataWithRange:NSMakeRange(responseOffset, responseLength)]];
        
        // 3. 判断请求资源是否结束
        if (responseLength >= requestLength) {
            // 资源请求已经获取到了所有的数据，请求结束
            [loadingRequest finishLoading];
            [loadedRequestList addObject:loadingRequest];
        }
    }
    
    [self.loadingRequestList removeObjectsInArray:loadedRequestList];
}

- (void)loadLocalDataWithResourceRequest:(AVAssetResourceLoadingRequest *)loadingRequest
{
    NSURL *url = [loadingRequest.request.URL httpURL];
    
    // 1. 信息头
    loadingRequest.contentInformationRequest.contentLength = [GRRemotePlayerFileManager cacheSizeWithURL:url];
    loadingRequest.contentInformationRequest.contentType = [GRRemotePlayerFileManager contentTypeWithURL:url];
    loadingRequest.contentInformationRequest.byteRangeAccessSupported = YES;
    
    // 2. 塞音频数据
    long long requestOffset = loadingRequest.dataRequest.requestedOffset;
    NSInteger requestLength = loadingRequest.dataRequest.requestedLength;
    
    NSString *path = [GRRemotePlayerFileManager cachePathWithURL:url];
    NSData *data = [NSData dataWithContentsOfFile:path options:NSDataReadingMappedIfSafe error:nil];
    
    NSData *subdata = [data subdataWithRange:NSMakeRange(requestOffset, requestLength)];
    [loadingRequest.dataRequest respondWithData:subdata];
    
    // 3. 资源请求结束
    [loadingRequest finishLoading];
}


@end
